Contents

  1. Imports
  2. Topics cum Notes
    1. L5
      1. Innovation
      2. Limited Liability
      3. Inflation Indexed Debt
      4. Unidad de Fomento
    2. L6
      1. Forecasting
      2. Random Walk
      3. First Order Auto Regressive Model
      4. Efficient Market Hypothesis
      5. Price as PDV
    3. L7
      1. Behavioral Finance
      2. Expected Utility Theory
      3. Value Function
      4. Prospect Theory
      5. Logical Fallacies
      6. Anchoring

Imports¶

In [ ]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import mplfinance as mpf
import matplotlib.dates as mdates
import datetime as dt

import plotly.graph_objects as go
import plotly.express as px
import plotly.io as pio
from plotly.subplots import make_subplots

pio.renderers.default = "notebook"
pio.templates.default = "plotly_dark"
import gc

np.random.seed(42)
In [ ]:
import warnings

warnings.filterwarnings("ignore")
In [ ]:
plt.rcParams["figure.figsize"] = [12, 8]

Topics cum Notes¶

L5¶

Innovation¶

Limited Liability¶

The idea is that investors, in order to be encouraged to invest in businesses, should have protection against liability for what the managers of the business do. So, an investor should not be liable for the debts or mistake of the business. This is the idea of limited liability.

The idea wah enuciated first in 1811 by New York State.

Inflation Indexed Debt¶

Instead of using a currency which is liable of changes, inflation indexed debt uses some index to tie the debt to that index.

Unidad de Fomento¶

A way to deal with inflation.

L6¶

Forecasting¶

Something that happended on past is not the represenative of what will happen in future.

Random Walk¶

Random walk theory suggests that changes in stock prices have the same distribution and are independent of each other. Therefore, it assumes the past movement or trend of a stock price or market cannot be used to predict its future movement. In short, random walk theory proclaims that stocks take a random and unpredictable path that makes all methods of predicting stock prices futile in the long run.

We have

$$ x_{t} = x_{t-1}+\epsilon_t $$

where $\epsilon$ is a noise and is completely unforcastable.

In [ ]:
apple = pd.read_csv("Data/AAPL.csv", parse_dates=["Date"], index_col="Date")
google = pd.read_csv("Data/GOOG.csv", parse_dates=["Date"], index_col="Date")
apple.head()
Out[ ]:
Open High Low Close Volume
Date
1980-12-12 00:00:00-05:00 0.099874 0.100308 0.099874 0.099874 469033600
1980-12-15 00:00:00-05:00 0.095098 0.095098 0.094663 0.094663 175884800
1980-12-16 00:00:00-05:00 0.088149 0.088149 0.087715 0.087715 105728000
1980-12-17 00:00:00-05:00 0.089886 0.090320 0.089886 0.089886 86441600
1980-12-18 00:00:00-05:00 0.092492 0.092927 0.092492 0.092492 73449600
In [ ]:
apple = apple[apple.index >= pd.to_datetime("2022-01-01", format="%Y-%m-%d", utc=True)]
apple = apple[["Close"]]
apple.head()
Out[ ]:
Close
Date
2022-01-03 00:00:00-05:00 180.959732
2022-01-04 00:00:00-05:00 178.663071
2022-01-05 00:00:00-05:00 173.910660
2022-01-06 00:00:00-05:00 171.007507
2022-01-07 00:00:00-05:00 171.176544
In [ ]:
px.line(apple, x=apple.index, y="Close", title="Apple Stock Price")
In [ ]:
sigma = apple["Close"].std()
print("Standard Deviation: ", sigma)
Standard Deviation:  12.466134262158613
In [ ]:
sigma = 3
In [ ]:
walk_prices = []
start_price = apple["Close"].iloc[-1]
cur_price = start_price
walk_prices.append(cur_price)
for i in range(1, 200):
    cur_price = cur_price + np.random.normal(0, sigma)
    walk_prices.append(cur_price)

walk_prices = np.array(walk_prices)
In [ ]:
fig = px.line(x=range(0, 200), y=walk_prices, title="Apple Stock Price (Random Walk)")
fig.update_xaxes(title_text="Days")
fig.update_yaxes(title_text="Price")
fig.show()

Let's merge both the plots on one graph.

In [ ]:
# walk_prices = np.array(walk_prices)
# prices = np.concatenate((apple["Close"].values, new_prices))
# prices = pd.DataFrame(prices, columns=["Close"])
# prices.index = apple.index.append(pd.date_range(start=apple.index[-1], periods=200, freq="D"))
# prices.head()
In [ ]:
fig = px.line(
    y=apple["Close"], x=np.arange(0, len(apple["Close"])), title="Apple Stock Price"
)
fig.add_scatter(
    y=walk_prices,
    x=np.arange(len(apple["Close"]), len(apple["Close"]) + len(walk_prices)),
    mode="lines",
    name="Random Walk",
)

Next, we'll repeat the simulation a number of times and plot the results.

In [ ]:
def simulate_one(days=200, sigma=3):
    walk_prices = []
    start_price = apple["Close"].iloc[-1]
    cur_price = start_price
    walk_prices.append(cur_price)
    for i in range(1, 200):
        cur_price = cur_price + np.random.normal(0, sigma)
        walk_prices.append(cur_price)

    walk_prices = np.array(walk_prices)
    return walk_prices
In [ ]:
# simulate 100 random walks and plot them
# We'll also plot the mean of the random walks
walk_prices = simulate_one()
sum_walk_price = walk_prices
fig = px.line(y=walk_prices, x=np.arange(0, 200))
for i in range(100):
    walk_prices = simulate_one()
    sum_walk_price += walk_prices
    fig.add_scatter(y=walk_prices, x=np.arange(0, 200), mode="lines", name=f"S_{i+1}")
fig.add_scatter(
    y=sum_walk_price / 100,
    x=np.arange(0, 200),
    mode="lines",
    name=f"Avereged",
    line=dict(color="royalblue", width=4),
)
fig.show()

First Order Auto Regressive Model¶

In this case, we have

$$ x_t = x_0 + \rho(x_{t-1}-x_0) + \epsilon _t $$

$x_0$ is the initial position. If $\rho =1$ this gives the random walk.

This is a modified version of random walk. The middle term means that as the position is away from the mean position, it will try to move to the mean position.

In [ ]:
rho = 0.1
ar_prices = []
start_price = apple["Close"].iloc[-1]
cur_price = start_price
ar_prices.append(cur_price)
for i in range(1, 200):
    cur_price = (
        start_price + rho * (cur_price - start_price) + np.random.normal(0, sigma)
    )
    ar_prices.append(cur_price)

fig = px.line(
    y=apple["Close"], x=np.arange(0, len(apple["Close"])), title="Apple Stock Price"
)
fig.add_scatter(
    y=ar_prices,
    x=np.arange(len(apple["Close"]), len(apple["Close"]) + len(ar_prices)),
    mode="lines",
    name=f"AR(1) for rho={rho}",
)
In [ ]:
rho = 0.5
ar_prices = []
start_price = apple["Close"].iloc[-1]
cur_price = start_price
ar_prices.append(cur_price)
for i in range(1, 200):
    cur_price = (
        start_price + rho * (cur_price - start_price) + np.random.normal(0, sigma)
    )
    ar_prices.append(cur_price)

fig = px.line(
    y=apple["Close"], x=np.arange(0, len(apple["Close"])), title="Apple Stock Price"
)
fig.add_scatter(
    y=ar_prices,
    x=np.arange(len(apple["Close"]), len(apple["Close"]) + len(ar_prices)),
    mode="lines",
    name=f"AR(1) for rho={rho}",
)
In [ ]:
rho = 0.9
ar_prices = []
start_price = apple["Close"].iloc[-1]
cur_price = start_price
ar_prices.append(cur_price)
for i in range(1, 200):
    cur_price = (
        start_price + rho * (cur_price - start_price) + np.random.normal(0, sigma)
    )
    ar_prices.append(cur_price)

fig = px.line(
    y=apple["Close"], x=np.arange(0, len(apple["Close"])), title="Apple Stock Price"
)
fig.add_scatter(
    y=ar_prices,
    x=np.arange(len(apple["Close"]), len(apple["Close"]) + len(ar_prices)),
    mode="lines",
    name=f"AR(1) for rho={rho}",
)
In [ ]:
rho = 1.0
ar_prices = []
start_price = apple["Close"].iloc[-1]
cur_price = start_price
ar_prices.append(cur_price)
for i in range(1, 200):
    cur_price = (
        start_price + rho * (cur_price - start_price) + np.random.normal(0, sigma)
    )
    ar_prices.append(cur_price)

fig = px.line(
    y=apple["Close"], x=np.arange(0, len(apple["Close"])), title="Apple Stock Price"
)
fig.add_scatter(
    y=ar_prices,
    x=np.arange(len(apple["Close"]), len(apple["Close"]) + len(ar_prices)),
    mode="lines",
    name=f"AR(1) for rho={rho}",
)

Same as before, we'll make a plot with multiple simulations. We'll be using $\rho = 0.9$

In [ ]:
def simulate_one(days=200, sigma=3, rho=0.9):
    ar_prices = []
    start_price = apple["Close"].iloc[-1]
    cur_price = start_price
    ar_prices.append(cur_price)
    for i in range(1, 200):
        cur_price = (
            start_price + rho * (cur_price - start_price) + np.random.normal(0, sigma)
        )
        ar_prices.append(cur_price)

    ar_prices = np.array(ar_prices)
    return ar_prices
In [ ]:
ar_prices = simulate_one()
sum_ar_price = ar_prices
fig = px.line(y=ar_prices, x=np.arange(0, 200))
for i in range(100):
    ar_prices = simulate_one()
    sum_ar_price += ar_prices
    fig.add_scatter(y=ar_prices, x=np.arange(0, 200), mode="lines", name=f"S_{i+1}")
fig.add_scatter(
    y=sum_ar_price / 100,
    x=np.arange(0, 200),
    mode="lines",
    name=f"Avereged",
    line=dict(color="royalblue", width=4),
)
fig.show()

Efficient Market Hypothesis¶

Weak Form: prices incorporate information about past prices

Semi Strong Form: all publicly information is already incorporated in the market prices

Strong Form: all information including inside information held by the companies is already incorporated in the stock prices, prices because it leaks out.

The hypothesis is only a "half truth".

Price as PDV¶

Discounted present value is a concept in economics and finance that refers to a method of measuring the value of payments or utility that will be received in the future. Most people would agree that receiving $1,000 today is better than receiving $1,000 in a year, because $1,000 today can be used for consumption or investment.

By Gordon model, if the earnings by a stock is due to dividends and the dividends grow with factor g, we have:

$$ P = \frac{E}{r-g}\\ \frac{P}{E} = \frac{1}{r-g} $$

$E$ can be seen as the value of the next year's dividends.

This means that if the P/E ratio is higher it would either have to be because it's low risk as measured by beta, so we willing to pay more for it because it's low risk. Or would have to be that people have reason to think that they're earning path the gross rate g is high.

L7¶

Behavioral Finance¶

Expected Utility Theory¶

People are rational and are trying to maximize their utility which is an measure of happiness.

Value Function¶

Example: Let's say I toss a coin. If it turns head, I'll give you 200 and if it turns tail you'll give me 100. So, you have an expected return of 50. By expected utility theory, you should take the bet. However, people don't usually take the bet.

This can be understood by the prospect thoery. People don't take the bet because the gaining 200 gives a little happiness but losing 100 gives a lot of unhappiness. This is called the loss aversion namely, people are more afraid of loosing. ("You are always worried about little losses today.")

Prospect Theory¶

Prospect theory is is a experimentally based set of knowledge about mistakes that people make. This is based on research by Kahneman and Tversky of people making decisions under uncertainty and is a modification of the expected utility theory. The theory is based on some real life facts such as:

  1. People are overly focused on little losses, little gains and losses.
  2. Another thing is that people will often try to gamble out of losses. If you went to the casino and you lost money, you think, maybe I should gamble some more, maybe I can get back to where I was.
  3. People have a skewed representation of probability, and they do not treat gains and losses equivalently.

The main assumption of the prospect theory is that people are not very ration which is in contrast with the traditional economic models that people are very sensible and calculating.

Efficient market hypothesis and behavioral finance are two main revolution of past 50-60 years. These two revolutions are kind of incompatible views of the world. But they both offer insights, they're both exciting.

Logical Fallacies¶

  1. Overconfidence
  2. Wishful Thinking Bias: People overestimate the probability of the things that they identify with and want to see happen. Very simple, you ask people what they think the probability of their team winning is. And it's always higher if it's their team.
  3. Overconfidence in Friends or Leaders

Anchoring¶

Anchoring refers to a tendency in ambiguous situations to allow one's decisions to be affected by some anchor. it's the same way I think with stock prices, that stock prices are anchored to past values. Nobody knows what this company is worth but it was worth something yesterday.